﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Road3App.Model;
using System.Collections.ObjectModel;
using System.Timers;
using Road3App.Model.RoadNs;

using Road3App.Views.UserControls;
using Road3App.Model.CrossroadNs;
using Road3App.Views.UserControls.EditControls;
using Road3App.Views;

namespace Road3App.ViewModels
{
    class MainViewModel : ViewModelBase
    {
        private string FilePath;

        private RoadNetwork _roadNetwork;
        public RoadNetwork RoadNetwork
        {
            get { return _roadNetwork; }
            set
            {
                _roadNetwork = value;
                RaisePropertyChanged("RoadNetwork");
            }
        }

        private IRoadNetworkSerializer _serizlizer;

        private ObservableCollection<TransformControl> _ContainerCollection;
        public ObservableCollection<TransformControl> ContainerCollection
        {
            get { return _ContainerCollection; }
            set
            {
                _ContainerCollection = value;
                RaisePropertyChanged("ContainerCollection");
            }
        }

        private bool _isRunning;
        public bool IsRunning
        {
            get { return _isRunning; }
            set
            {
                _isRunning = value;
                RaisePropertyChanged("IsRunning");
            }
        }
                
        public MainViewModel()
        {
            NewRoadNetwork();

            _serizlizer = new XmlRoadNetworkSerializer();
        }

        private void SetEventHandlers()
        {
            RoadNetwork.ContainerAdded += (s, ea) => this.ContainerCollection.Add(CreateUC(ea.Container));
            RoadNetwork.ContainerRemoved += (s, ea) =>
            {
                var uc =
                    this.ContainerCollection
                    .Where(c => (c.DataContext as Container) == ea.Container)
                    .FirstOrDefault();

                if (uc != null)
                    this.ContainerCollection.Remove(uc);
            };
        }

        public void NewRoadNetwork()
        {
            RoadNetwork = new RoadNetwork();
            SetEventHandlers();
            UpdateContainerCollection();            
        }

        public void LoadNetwork()
        {
            string path = Services.DialogService.Open();
            if (!string.IsNullOrWhiteSpace(path))
            {
                this.RoadNetwork = _serizlizer.Load(path);
                SetEventHandlers();
                UpdateContainerCollection();
                this.FilePath = path;
            }            
        }

        public void SaveNetwork()
        {
            if (!string.IsNullOrWhiteSpace(this.FilePath))
                _serizlizer.Save(this.FilePath, this.RoadNetwork);
            else
                SaveNetworkAs();
        }

        public void SaveNetworkAs()
        {
            string path = Services.DialogService.Save();
            if (!string.IsNullOrWhiteSpace(path))
            {
                _serizlizer.Save(path, this.RoadNetwork);
            }
        }

        public void InitTest()
        {
            var road = new Road { X = 50, Y = 50, SpeedLimit = 20, Lanes = 2, Length = 300 };
            var vg = new VehicleGenerator();
            vg.NextContainer = road;
            RoadNetwork.AddRoad(road);
            RoadNetwork.AddVehGen(vg);
        }

        private TransformControl CreateUC(Container container)
        {
            if (container is Road)
                return new RoadUC(container as Road);
            else if (container is CrossRoad)
                return new CrossRoadUC(container as CrossRoad);
            else if (container is VehicleGenerator)
                return new VehicleGeneratorUC(container as VehicleGenerator);
            else
                throw new ArgumentException("unknown container type", "container");
        }

        private void UpdateContainerCollection()
        {
            this.ContainerCollection = new ObservableCollection<TransformControl>();

            foreach (var road in RoadNetwork.RoadCollection)
                this.ContainerCollection.Add(new RoadUC(road));

            foreach (var cr in RoadNetwork.CRCollection)
                this.ContainerCollection.Add(new CrossRoadUC(cr));

            foreach (var vg in RoadNetwork.VGCollection)
                this.ContainerCollection.Add(new VehicleGeneratorUC(vg));
        }

        public void StartStop()
        {
            if (IsRunning)
            {
                RoadNetwork.Stop();
                IsRunning = false;
            }
            else
            {
                RoadNetwork.Start();
                IsRunning = true;
            }
        }

        public void ConnectContainers(Container first, Container second)
        {
            if (first is Road)
            {
                if (second is Road)
                {
                    Road road1 = first as Road;
                    Road road2 = second as Road;

                    road1.NextContainer = road2;
                }
                else if (second is CrossRoad)
                {
                    Road road = first as Road;
                    CrossRoad cr = second as CrossRoad;

                    road.NextContainer = cr;

                    AddConnectorViewModel vm = new AddConnectorViewModel(cr, road, "press on start cells from center of road");
                    AddConnectorUC uc = new AddConnectorUC() { DataContext = vm };
                    EditWindow ew = new EditWindow(uc);

                    if ((bool)ew.ShowDialog())
                    {
                        RCRConnector.AddConnections(cr, road, vm.CellSequence);
                    }
                }
            }
            else if (first is CrossRoad)
            {
                if (second is Road)
                {
                    CrossRoad cr = first as CrossRoad;
                    Road road = second as Road;

                    AddConnectorViewModel vm = new AddConnectorViewModel(cr, road, "press on finish cells from center of road");
                    AddConnectorUC uc = new AddConnectorUC() { DataContext = vm };
                    EditWindow ew = new EditWindow(uc);

                    if ((bool)ew.ShowDialog())
                    {
                        RCRConnector.AddConnections(cr, road, vm.CellSequence);
                    }
                }
            }
            else if (first is VehicleGenerator)
            {
                if (second is Road)
                {
                    VehicleGenerator vg = first as VehicleGenerator;
                    Road road = second as Road;

                    vg.NextContainer = road;
                }
            }
        }


    }
}
